﻿using System;
using System.Linq;
using System.Reflection;
using System.Diagnostics;

namespace BookStore
{
    class Menu
    {
        static StoreEngine engine = StoreEngine.GetEngine();

        public static string[] order = new string[7];
        private static Item currentItem;
        // This list will store the choises the consumer has made through the menu.
        // order[0] = type - book or multimedia
        // order[1] = content type - Fiction, Nonfiction, TextBook (Book); Ebook, Audio, Video (Media) 
        // order[2] = genre
        // order[3] = Video
        // order[4] = Audio
        // order[5] = E_Book
        // order[6] = quantity

        // Menu Level 01 - START
        public static void MenuStart()
        {
            System.Diagnostics.Debug.WriteLine("\nPlease choose the type of book/media you would like to order:\n");
            System.Diagnostics.Debug.WriteLine(new String('-', 58));

            System.Diagnostics.Debug.WriteLine("\n1.  Book");
            System.Diagnostics.Debug.WriteLine("2.  Multimedia\n");

            switch (System.Diagnostics.Debug.ReadLine())
            {
                case "1": System.Diagnostics.Debug.Clear();
                    Menu.order[0] = "book";
                    MenuType(1);
                    break;
                case "2": System.Diagnostics.Debug.Clear();
                    Menu.order[0] = "multimedia";
                    MenuType(2);
                    break;
                default: System.Diagnostics.Debug.WriteLine("Please enter 1 or 2 and than press [ENTER]!");
                    System.Diagnostics.Debug.ReadLine();
                    System.Diagnostics.Debug.Clear();
                    break;
            }
        }

        // Menu Level 02
        public static void MenuType(int type)
        {
            if (type == 1)  // book (hardcopy) - contentType Fiction, Nonfiction, TextBook
            {
                System.Diagnostics.Debug.WriteLine("\nPlease choose the content type of book now:\n");
                System.Diagnostics.Debug.WriteLine(new String('-', 58));
                System.Diagnostics.Debug.WriteLine();

                string[] contentType = {"Fiction", "Nonfiction", "TextBook"};

                for (int i = 0; i < 3; i++)
                {
                    System.Diagnostics.Debug.WriteLine("{0}.  {1}", i + 1, contentType[i]);
                }

                System.Diagnostics.Debug.WriteLine("\n{0}.  Go back\n", contentType.Length + 1);
                
                int input = int.Parse(System.Diagnostics.Debug.ReadLine());

                if (input > 0 && input <= contentType.Length + 1)
                {
                    if (input == contentType.Length + 1)
                    {
                        System.Diagnostics.Debug.Clear();
                        MenuStart();
                    }
                    else
                    {
                        Menu.order[1] = Convert.ToString(contentType[input - 1]);
                        System.Diagnostics.Debug.Clear();
                        MenuContentType(contentType[input - 1]);
                    }
                }
                else 
                {
                    System.Diagnostics.Debug.WriteLine("\nPlease enter a number between 1 and {0} and than press [ENTER]!", contentType.Length + 1);
                    input = int.Parse(System.Diagnostics.Debug.ReadLine());
                    System.Diagnostics.Debug.Clear();
                    MenuType(1);
                }
            }
            else if (type == 2)     //  media (electronic media) - Ebook, Audio, Video
            {
//                Publisher[] multimediaPublishers = multimedias.Select(x => x.Publisher).Distinct().Cast<Publisher>().ToArray();

                System.Diagnostics.Debug.WriteLine("\nPlease choose the content type of media now:\n");
                System.Diagnostics.Debug.WriteLine(new String('-', 58));
                System.Diagnostics.Debug.WriteLine();

                string[] contentType = { "Ebook", "Audio", "Video" };

                for (int i = 0; i < 3; i++)
                {
                    System.Diagnostics.Debug.WriteLine("{0}.  {1}", i + 1, contentType[i]);
                }

                System.Diagnostics.Debug.WriteLine("\n{0}.  Go back\n", contentType.Length + 1);

                int input = int.Parse(System.Diagnostics.Debug.ReadLine());

                if (input > 0 && input <= contentType.Length + 1)
                {
                    if (input == contentType.Length + 1)
                    {
                        System.Diagnostics.Debug.Clear();
                        MenuStart();
                    }
                    else
                    {
                        Menu.order[1] = Convert.ToString(contentType[input - 1]);
                        System.Diagnostics.Debug.Clear();
                        MenuContentType(contentType[input - 1]);
                    }
                }
                else
                {
                    System.Diagnostics.Debug.WriteLine("\nPlease enter a number between 1 and {0} and than press [ENTER]!", contentType.Length + 1);
                    input = int.Parse(System.Diagnostics.Debug.ReadLine());
                    System.Diagnostics.Debug.Clear();
                    MenuType(1);
                }
            }
        }

        // Menu Level 03
        public static void MenuContentType(string contentType)
        {
            System.Diagnostics.Debug.WriteLine("\nPlease choose a {0} genre:\n", contentType);
            System.Diagnostics.Debug.WriteLine(new String('-', 58));
            System.Diagnostics.Debug.WriteLine();

            if (order[0] == "book")
            {
                Book[] books = engine.GetAllAvailableItemsFromType<Book>();
                Book[] bookGenres = books.Where(x => x.ContentType == contentType).Cast<Book>().ToArray();

                for (int i = 0; i < bookGenres.Length; i++)
                {
                    System.Diagnostics.Debug.WriteLine("{0}.  {1}", i + 1, bookGenres[i]);
                }

                System.Diagnostics.Debug.WriteLine("\n{0}.  Go back\n", bookGenres.Length + 1);

                int input = int.Parse(System.Diagnostics.Debug.ReadLine());

                if (input > 0 && input <= bookGenres.Length + 1)
                {
                    if (input == bookGenres.Length + 1)
                    {
                        System.Diagnostics.Debug.Clear();
                        MenuType(1);
                    }
                    else
                    {
                        Menu.order[2] = Convert.ToString(bookGenres[input - 1].ContentType);
                        System.Diagnostics.Debug.Clear();
                        currentItem = bookGenres[input - 1];
                        MenuQuantity();
                    }
                }
                else
                {
                    System.Diagnostics.Debug.WriteLine("\nPlease enter a number between 1 and {0} and than press [ENTER]!", bookGenres.Length + 1);
                    input = int.Parse(System.Diagnostics.Debug.ReadLine());
                }
            }
            else if (order[0] == "multimedia")
            {
                Media[] medias = engine.GetAllAvailableItemsFromType<Media>();
                Media[] mediaGenres = medias.Where(x => x.ContentType == contentType).Cast<Media>().ToArray();

                for (int i = 0; i < mediaGenres.Length; i++)
                {
                    System.Diagnostics.Debug.WriteLine("{0}.  {1}", i + 1, mediaGenres[i]);
                }

                System.Diagnostics.Debug.WriteLine("\n{0}.  Go back\n", mediaGenres.Length + 1);

                int input = int.Parse(System.Diagnostics.Debug.ReadLine());

                if (input > 0 && input <= mediaGenres.Length + 1)
                {
                    if (input == mediaGenres.Length + 1)
                    {
                        System.Diagnostics.Debug.Clear();
                        MenuType(1);
                    }
                    else
                    {
                        Menu.order[2] = Convert.ToString(mediaGenres[input - 1].ContentType);
                        System.Diagnostics.Debug.Clear();
                        currentItem = mediaGenres[input - 1];
                        MenuQuantity();
                    }
                }
                else
                {
                    System.Diagnostics.Debug.WriteLine("\nPlease enter a number between 1 and {0} and than press [ENTER]!", mediaGenres.Length + 1);
                    input = int.Parse(System.Diagnostics.Debug.ReadLine());
                }               
            }
        }

        // Menu Level 04
        public static void MenuQuantity()
        {
            bool correctInput = false;
            while (!correctInput)
            {
                System.Diagnostics.Debug.WriteLine("\nPlease enter the desired quantity or B to go back:\n");
                System.Diagnostics.Debug.WriteLine(new String('-', 58));
                System.Diagnostics.Debug.WriteLine();

                string input = System.Diagnostics.Debug.ReadLine();
                try
                {
                    if (input == "B" || input == "b")
                    {
                        System.Diagnostics.Debug.Clear();
                        MenuContentType((string)Enum.Parse(typeof(Book), order[1]));
                    }
                    else if (int.Parse(input) <= 0)
                    {
                        throw new ArgumentOutOfRangeException("Invalid choice!");                    
                    }
                    else
                    {
                        Menu.order[6] = input;
                        MenuPurchase(int.Parse(input));
                    }
                    correctInput = true;
                }
                catch (ArgumentOutOfRangeException e)
                {
                    System.Diagnostics.Debug.Clear();
                    System.Diagnostics.Debug.WriteLine(e.Message);
                }
            }
        }

        // Menu Level 05 - END
        public static void MenuPurchase(int quantity)
        {
            System.Diagnostics.Debug.Clear();
            System.Diagnostics.Debug.WriteLine("\nYour order is:\n");
            System.Diagnostics.Debug.WriteLine(currentItem);
            System.Diagnostics.Debug.WriteLine("Quantity: {0}", quantity); 
            System.Diagnostics.Debug.WriteLine(new String('-', 58));

            try
            {
                engine.ExtractStock(currentItem.Id, quantity);
                System.Diagnostics.Debug.WriteLine("Your purchase was processed successfully!");
            }
            catch (InsufficientStockException<int> e)
            {
                System.Diagnostics.Debug.WriteLine("{0} for item with ID: {1}", e.Message, e.ItemId);
                System.Diagnostics.Debug.WriteLine("Remaining quantity: {0}", e.Quantity);
            }
            System.Diagnostics.Debug.ReadLine();
        }
    }
}
